1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include <cstdio> #include <cstring> #include <queue> #include <cctype> const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; const int SS = 403; const int TT = 404; using namespace std; struct E{ int to, nxt, f; }e[maxn << 1]; int d[405], head[405], tot = 1; void addedge(int u, int v, int f){ e[++tot].to = v, e[tot].nxt = head[u], e[tot].f = f; head[u] = tot; } void ins(int u, int v, int l, int r){ d[u] -= l; d[v] += l; addedge(u, v, r - l); addedge(v, u, 0); } int dep[405], now[405]; bool bfs(){ queue <int> q; while (!q.empty()) q.pop(); q.push(SS); memset(dep, 0, sizeof dep); dep[SS] = 1; memcpy(now, head, sizeof now); while (!q.empty()){ int cur = q.front(); q.pop(); for (int i = head[cur]; i; i = e[i].nxt){ int v = e[i].to; if (e[i].f > 0 && dep[v] == 0){ dep[v] = dep[cur] + 1; q.push(v); } } } return dep[TT] > 0; } int dfs(int cur, int Max){ if (cur == TT) return Max; int flow = 0; for (int i = now[cur]; i; i = e[i].nxt){ now[cur] = i; int v = e[i].to; if (e[i].f > 0 && dep[v] == dep[cur] + 1){ int tmp = dfs(v, min(Max - flow, e[i].f)); flow += tmp; e[i].f -= tmp; e[i ^ 1].f += tmp; if (flow == Max) return flow; } } return flow; } int maxflow; void Dinic(){ maxflow = 0; while (bfs()) maxflow += dfs(SS, INF); } int n, m, l[205], c[205], L, R; bool check(int mid){ memset(head, 0, sizeof head); tot = 1; memset(d, 0, sizeof d); int S = 0, T = n + m + 1; for (int i = 1; i <= n; i++){ ins(S, i, l[i] - mid, l[i] + mid); for (int j = 1; j <= m; j++) ins(i, j + n, L, R); } int sum = 0; for (int i = 1; i <= m; i++) ins(i + n, T, c[i] - mid, c[i] + mid); for (int i = 0; i <= n + m + 1; i++) if (d[i] > 0) sum += d[i], addedge(SS, i, d[i]), addedge(i, SS, 0); else if (d[i] < 0) addedge(i, TT, -d[i]), addedge(TT, i, 0); addedge(T, S, INF); Dinic(); return maxflow == sum; } int main(){ scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) for (int a, j = 1; j <= m; j++){ scanf("%d", &a); l[i] += a; c[j] += a; } scanf("%d%d", &L, &R); int l = 0, r = 4e5, ans; while (l <= r){ int mid = l + r >> 1; if (check(mid)) ans = mid, r = mid - 1; else l = mid + 1; } printf("%d\n", ans); return 0; }
|